package other.xsy.pms;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rkhd.platform.sdk.api.annotations.RequestMethod;
import com.rkhd.platform.sdk.api.annotations.RestApi;
import com.rkhd.platform.sdk.api.annotations.RestMapping;
import com.rkhd.platform.sdk.api.annotations.RestQueryParam;
import com.rkhd.platform.sdk.common.OauthConfig;
import com.rkhd.platform.sdk.creekflow.approvalevent.ApprovalEvent;
import com.rkhd.platform.sdk.creekflow.approvalevent.ApprovalEventRequest;
import com.rkhd.platform.sdk.creekflow.approvalevent.ApprovalEventResponse;
import com.rkhd.platform.sdk.creekflow.ruleevent.RuleEventResponse;
import com.rkhd.platform.sdk.data.model.Opportunity;
import com.rkhd.platform.sdk.data.model.User;
import com.rkhd.platform.sdk.exception.*;
import com.rkhd.platform.sdk.http.RkhdHttpClient;
import com.rkhd.platform.sdk.http.RkhdHttpData;
import com.rkhd.platform.sdk.log.Logger;
import com.rkhd.platform.sdk.log.LoggerFactory;
import com.rkhd.platform.sdk.model.QueryResult;
import com.rkhd.platform.sdk.model.XObject;
import com.rkhd.platform.sdk.service.XoqlService;
import com.rkhd.platform.sdk.trigger.DataResult;
import com.rkhd.platform.sdk.trigger.Trigger;
import com.rkhd.platform.sdk.trigger.TriggerRequest;
import com.rkhd.platform.sdk.trigger.TriggerResponse;
import org.apache.commons.lang.StringUtils;
import other.xsy.pms.utils.*;

import java.io.IOException;
import java.io.StreamCorruptedException;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 功能描述：同步销售机会到pms系统
 *
 * @author 黄梓豪
 * @ClassName: PhasePromotionRuleEventImpl
 * @Description:
 * @date 2024年03月13日
 */
@RestApi(baseUrl = "/opportunity")
public class SyncOpportunityToPmsTrigger implements Trigger, ApprovalEvent {

    private static HCXObjectService hcxObjectService = new HCXObjectService();
    private static final Logger logger = LoggerFactory.getLogger();

    private static String LOGGER_MSG = "新增、编辑、转移同步销售机会到pms系统 ==> ";


    /**
     * Trigger 触发事件
     * @param request
     * @return
     * @throws ScriptBusinessException
     */
    @Override
    public TriggerResponse execute(TriggerRequest request) throws ScriptBusinessException {
        logger.debug(LOGGER_MSG + " 触发开始 ");
        List<XObject> dataList = request.getDataList();
        List<DataResult> dataResultList = new ArrayList<>();
        ArrayList<Opportunity> opportunitiesList = new ArrayList<>();
        for (XObject xObject : dataList) {
            Opportunity opportunity = (Opportunity) xObject;
            opportunitiesList.add(opportunity);
            dataResultList.add(new DataResult(true, "", xObject));
        }
        executeSync(opportunitiesList.get(0).getId());
        return new TriggerResponse(true, "处理完成", dataResultList);
    }

    /**
     * 审批触发事件
     * @param request
     * @return
     * @throws ScriptBusinessException
     */
    @Override
    public ApprovalEventResponse execute(ApprovalEventRequest request) throws ScriptBusinessException {
        logger.info(LOGGER_MSG + " 触发开始 ");
        logger.info("ObjectApiKey:" + request.getEntityApiKey() + " , DataId:" + request.getDataId());
        logger.info(request.toString());
        ApprovalEventResponse response = new ApprovalEventResponse();
        response.setSuccess(true);
        response.setMsg("success");
        executeSync(request.getDataId());
        return response;
    }

    /**
     * @param id
     * @return
     */
    @RestMapping(value = "/pushPMS", method = RequestMethod.POST)
    public String pushPMS(@RestQueryParam(name = "id") String id) {
        logger.info("执行了按钮事件");
        RuleEventResponse response = this.executeSync(Long.valueOf(id));
        Boolean success = response.getSuccess();
        if (success) {
            return TfReturnMsgTools.getSuccessResult(response.getMsg());
        }
        return TfReturnMsgTools.getFailResult(response.getMsg());
    }


    public static void main(String[] args) throws Exception {
        SyncOpportunityToPmsTrigger syncOpportunityToPmsTrigger = new SyncOpportunityToPmsTrigger();
        syncOpportunityToPmsTrigger.executeSync(3527675697781422L);

        //String saleStageName = syncOpportunityToPmsTrigger.getSaleStageName(3179063442410798L, 11010000300001L);
        //System.out.println("saleStageName = " + saleStageName);

    }

    /**
     * 批量重置是否失效状态
     */
    public void batchUpItInvalid() throws ApiEntityServiceException {
        String sql = "select id,entityType from opportunity where IsItInvalid__c is null";
        QueryResult<JSONObject> query = XoqlService.instance().query(sql);
        System.out.println("query = " + query.getTotalCount());

        List<Opportunity> opportunityList = new ArrayList<>();
        List<JSONObject> records = query.getRecords();
        for (JSONObject record : records) {
            Opportunity opportunity = new Opportunity();
            opportunity.setId(record.getLong("id"));
            opportunity.setEntityType(record.getLong("entityType"));
            opportunity.setIsItInvalid__c(1);
            opportunityList.add(opportunity);
            if (opportunityList.size() >= 50) {
                Boolean update = hcxObjectService.batchUpdate(opportunityList);
                System.out.println("update = " + update);
                opportunityList.clear();
            }
        }
    }


    /**
     * 入参id, 方便定时任务执行
     * @param opportunityId
     * @return
     */
    public RuleEventResponse executeSync(Long opportunityId) {
        logger.debug(LOGGER_MSG + " 开始执行: " + opportunityId);
        RuleEventResponse response = new RuleEventResponse();
        Opportunity update = new Opportunity();
        update.setId(opportunityId);
        update.setSyncStatus__c(3); // 同步失败
        update.setErrorInfo__c("");
        Long count = 1L;
        int isUpdate = 1; // 商机识别不进行更新
        try {
            Opportunity opportunity = new Opportunity();
            opportunity.setId(opportunityId);
            opportunity = hcxObjectService.get(opportunity);
            logger.info(LOGGER_MSG + " 销售机会名称: " + opportunity.getOpportunityName());

            // 推送前置判断
            // 1. 业务类型为 渠道项目: 销售阶段不等于'商机识别' 且 审批通过
            // 2. 业务类型非 渠道项目：销售阶段不等于'商机识别''
            Long saleStageId = opportunity.getSaleStageId();
            Long entityType = opportunity.getEntityType();
            Integer approvalStatus = opportunity.getApprovalStatus();
            String saleStageName = getSaleStageName(saleStageId, entityType);
            String errorInfo = ""; // 有值代表不满足推送条件
            if (Objects.equals(saleStageName, "商机识别")) {
                errorInfo = "销售阶段等于【商机识别】无需推送";
            } else if (Objects.equals(entityType, 3379376946551403L) && approvalStatus != 3) {
                // 业务类型为【渠道项目】需要增加审批状态通过判断
                errorInfo = "业务类型为【渠道项目】需审批通过后才可推送";
            }

            // 不满足推送条件
            if (StringUtils.isNotBlank(errorInfo)) {
                isUpdate = 0;
                update.setErrorInfo__c(errorInfo);
                response.setSuccess(false);
                response.setMsg(errorInfo);
                logger.debug(LOGGER_MSG + errorInfo);
                return response;
            }

            logger.debug(LOGGER_MSG + " 销售阶段满足条件，开始执行同步");
            // 设置同步次数
            if (opportunity.getSyncCount__c() != null) {
                count += opportunity.getSyncCount__c();
            }

            // 调用业务代码方法
            pushPMS(opportunity, saleStageName);
            update.setSyncStatus__c(2); // 同步成功
            response.setSuccess(true);
            response.setMsg("同步成功");
            return response;
        } catch (Exception e) {
            String message = e.getMessage();
            response.setSuccess(false);
            update.setErrorInfo__c(message);
            logger.error("同步销售机会系统异常：" + message);
            response.setMsg("系统异常：" + message);
            e.printStackTrace();
            return response;
        } finally {
            try {
                if (isUpdate == 1) {
                    update.setSyncCount__c(count);
                }
                hcxObjectService.update(update);
            } catch (ApiEntityServiceException e) {
                throw new RuntimeException(e);
            }
        }

    }

    private void pushPMS(Opportunity opportunity, String saleStageName) throws Exception {
        //获取阶段名称z
        //Long saleStageId = opportunity.getSaleStageId();
        //Long entityType = opportunity.getEntityType();
        //String saleStageName = getSaleStageName(saleStageId, entityType);
        JSONArray requestMsg = buidlMsg(opportunity, saleStageName);
        logger.info("请求报文：" + requestMsg.toJSONString());
        JSONObject jsonObject = PromotionApiUtil.sendToPms(requestMsg, PromotionApiUtil.getSaleOpportunitiesUrl());
        String code = jsonObject.getString("code");
        if (!"0".equals(code)) {
            throw new ScriptBusinessException("同步失败");
        }
        JSONObject data = jsonObject.getJSONArray("data").getJSONObject(0);
        Integer result1 = data.getInteger("result");
        if (result1 == 0) {
            return;
        }
        String errMsg = data.getString("errMsg");
        throw new ScriptBusinessException(errMsg);
    }

    protected JSONArray buidlMsg(Opportunity opportunity, String saleStageName) throws Exception {
        JSONArray globalPick20 = ComUtils.getGlobalPicks("globalPick20__c"); // 来源
        JSONArray globalPick41 = ComUtils.getGlobalPicks("globalPick41__c"); // 项目交付类型

        JSONArray jsonArray = new JSONArray(); // 创建 JSONArray 对象
        //构建json
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("businessOpportunityNo", opportunity.getProjectCode__c());   //销售机会编码 必填
        jsonObject.put("businessOpportunityId", opportunity.getSF_ID__c() == null ? opportunity.getId() : opportunity.getSF_ID__c()); //销售机会ID
        jsonObject.put("businessOpportunityName", opportunity.getOpportunityName()); //销售机会名称
        Long sales = opportunity.getOwnerId(); // 销售
        Long preSales = opportunity.getPreSales__c();// 售前
        Map<Long, User> userMap = queryUserMap(Arrays.asList(sales, preSales));
        User user = userMap.get(preSales);
        User user2 = userMap.get(sales);
        jsonObject.put("presaleAccount", user == null ? "" : user.getLoginName__c());  //售前OA账号
        jsonObject.put("presaleAccountName", user == null ? "" : user.getName());  //售前OA账号
        jsonObject.put("sellAccount", user2 == null ? "" : user2.getLoginName__c()); //销售OA账号 必填
        jsonObject.put("sellAccountName", user2 == null ? "" : user2.getName()); // 销售用户名称
        jsonObject.put("customerNo", opportunity.getAccountNo__c());  //客户名称编码
        String sourceName = ComUtils.getOptionLabel(globalPick20, opportunity.getSource__c());
        jsonObject.put("businessSource", sourceName);  //业务机会来源名称
        String optionApiKey = ComUtils.getOptionApiKey(globalPick41, opportunity.getProjectDeliveryType__c());
        jsonObject.put("deliveryType", optionApiKey);    //项目交付类型编码
        jsonObject.put("salesStage", saleStageName);  //销售阶段名称
        jsonObject.put("salesStageEnd", HCDateUtils.longToString(opportunity.getCloseDate(), HCDateUtils.FORMAT)); //结单日期
        jsonObject.put("possibility", opportunity.getWinRate()); //可能性 使用赢率
        Integer productBU = opportunity.getProductBU__c();
        jsonObject.put("isBu", productBU == null ? null : productBU == 1);    //是否涉及产品BU

        /*
            是否失效（默认有效）
            crm 1:有效 2:失效
            pms 1：有效  0：失效 (String 类型)
         */
        String reserved = "1";
        if (Objects.equals(opportunity.getIsItInvalid__c(), 2)) {
            reserved = "0";
        }
        jsonObject.put("reserved2", reserved);

        // 业务类型
        Long entityType = opportunity.getEntityType();
        String entityName = CustomAdminUtil.getEntityValByKey("opportunity", entityType, "label");
        jsonObject.put("reserved3", entityType);
        jsonObject.put("reserved4", entityName);

        // 是否涉及返点 1:是  2: 否
        Integer isReturnPoint = opportunity.getIsReturnPoint__c();
        jsonObject.put("reserved5", isReturnPoint == null ? null : isReturnPoint == 1);

        jsonArray.add(jsonObject);
        return jsonArray;
    }

    private Map<Long, User> queryUserMap(List<Long> useridList) throws ApiEntityServiceException {
        useridList = useridList.stream().filter(data -> data != null).collect(Collectors.toList());
        String join = StringUtils.join(useridList, ",");
        String sql = "select id,name,LoginName__c from user where id in (" + join + ")";
        List<User> userList = (List<User>) hcxObjectService.query(sql);
        if (userList == null || userList.size() <= 0) {
            return new HashMap<>();
        }
        Map<Long, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, o -> o));
        return userMap;
    }

    public String getSaleStageName(Long saleStageId, Long entityType) throws Exception {
        //String entityApiKey = ComUtils.getEntityApiKey("opportunity", entityType);
        // 使用管理员权限查询
        String entityApiKey = CustomAdminUtil.getEntityValByKey("opportunity", entityType, "apiKey");
        if (entityApiKey == null) {
            throw new StreamCorruptedException("查询业务类型失败: " + entityType);
        }

        JSONArray stageListByEntityTypeApiKey = ComUtils.getStageListByEntityTypeApiKey(entityApiKey);
        for (Object o : stageListByEntityTypeApiKey) {
            JSONObject data = (JSONObject) o;
            Long id = data.getLong("id");
            if (id.equals(saleStageId)) {
                String stageName = data.getString("stageName");
                return stageName;
            }
        }
        logger.info("entityApiKey:" + entityApiKey + "  saleStageId:" + saleStageId);
        throw new StreamCorruptedException("获取销售阶段名称失败");
    }

}
